// 本文件增加对已登录用户的过滤以及对时间的显示

#include<stdio.h>
#include<stdlib.h>
#include<utmp.h>
#include<fcntl.h>// File open/read
#include<unistd.h>// File close
#include<time.h>

#define SHOWHOST

void show_info( struct utmp *utbufp );
void show_time( long timeval );

int main()
{
    struct utmp current_record;// man 5 utmp, structure of utmp
    int utmpfd;// utmp file descriptor
    int reclen = sizeof(current_record);

    // open utmp file
    if (-1 == (utmpfd = open(UTMP_FILE, O_RDONLY)))
    {
        perror(UTMP_FILE);// UTMP_FILE is in utmp.h
        exit(1);
    }

    while (reclen == read(utmpfd, &current_record, reclen))
    {
        show_info(&current_record);// read the utmp record & show it
    }

    close(utmpfd);

    return 0;
}

// 根据man 5 utmp中的宏定义可知，成员ut_type值为USER_PROCESS时为已登录用户
void show_info( struct utmp *utbufp )
{
    if(USER_PROCESS != utbufp->ut_type)
        return;

    time_t time = utbufp->ut_tv.tv_sec;

    printf("%-8.8s", utbufp->ut_user);  // Username
    printf(" ");

    printf("%-8.8s", utbufp->ut_line);  // Devide name of tty...
    printf(" ");

    printf("%s", utbufp->ut_host);  // Hostname for remote login
    printf(" ");

    show_time(time);
    printf("\n");
}

// notice member "struct timeval ut_tv",man -k timeval and that is timeradd
// and so on.
// man 3 timeradd, time_t is member of struct timrval

void show_time(long timeval)
{
    char *cp;
    cp = ctime(&timeval);

    // The call ctime(t) is equivalent to asctime(localtime(t)).  It  converts
    // the calendar time t into a null-terminated string of the form
    // "Wed Jun 30 21:49:08 1993\n"

    // display m-d-H-M-S
    printf("%12.12s", cp + 4);
}

